package com.lmaos.basetools.dbconn;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.dbcp.BasicDataSource;

import com.lmaos.basetools.base.SBaseUtils;
import com.lmaos.basetools.base.SParamMap;
import com.lmaos.basetools.dbconn.DBConf.Sql;


public class DBConn {
	private static Map<String, BasicDataSource> dataSources = new ConcurrentHashMap<String, BasicDataSource>(64); // 数据配置
	private static Map<String,Map<String, Sql>> sqlConfig = new ConcurrentHashMap<String, Map<String,Sql>>();	// sql配置
	/** 
	 * 说明：加载数据库连接池数据源		<br>
	 * 时间：2017年6月16日 下午1:12:34
	 *
	 * @param fileName classPath 下当文件名
	 */
	public static void loadPoolDataSourceByClassPath(String fileName){
		
		Map<String, BasicDataSource> ndataSources = DBConf.getDBDataSourcesByClassPath(fileName);
		for(Entry<String, BasicDataSource> entry : ndataSources.entrySet()){
			if(!dataSources.containsKey(entry.getKey())){
				dataSources.put(entry.getKey(), entry.getValue());
			}
		}

	}
	/**
	 * 说明：从连接池获得一个连接		<br>
	 * 时间：2017年6月16日 下午2:03:05
	 *
	 * @param name
	 * @return
	 * @throws SQLException 
	 */
	public static Connection getConnection(String name) throws SQLException{
		Connection connection = null;
		if(dataSources!=null){
			BasicDataSource dataSource = dataSources.get(name);
			if(dataSource != null){
				connection = dataSource.getConnection();
			}
		}
		return connection;
	}
	/**
	 * 说明：加载sql配置,可以通过配置方式获得sql		<br>
	 * 时间：2017年6月26日 上午9:29:45
	 *
	 * @param fileName
	 */
	public static void loadSqlConfigByClassPath(String fileName){
		Map<String,Map<String, Sql>> nsqlConfig = DBConf.getXmlSqlsByClassPath(fileName);
		for(Entry<String,Map<String, Sql>> entry : nsqlConfig.entrySet()){
			if(!sqlConfig.containsKey(entry.getKey())){
				sqlConfig.put(entry.getKey(), entry.getValue());
			}
		}
	}
	
	public static Sql getSql(String groupName,String sqlName){
		Map<String, Sql> sqls = sqlConfig.get(groupName);
		if(sqls == null){
			return null;
		}
		return sqls.get(sqlName);
	}
	
	/**
	 * 说明：获取一个数据库连接		<br>
	 * 时间：2017年6月16日 下午1:13:42
	 *
	 * @param driverClass 驱动类路径
	 * @param url		连接url字符
	 * @param user		用户
	 * @param password	密码
	 * @return
	 */
	public static Connection getConnection(String driverClass,String url,String user,String password){
		try {
			Class.forName(driverClass);
			return DriverManager.getConnection(url, user, password);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static String[] getColumnNames(ResultSet rs){
		try {
			ResultSetMetaData md = rs.getMetaData();
			String[] names = new String[md.getColumnCount()];
			for (int i = 0; i < names.length; i++) {
				names[i] = md.getColumnName(i+1);
			}
			return names;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static List<SParamMap> select(String sql,Connection conn,Object...params){
		List<SParamMap> list = new ArrayList<SParamMap>();
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sql);
			if(params!=null)
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i+1, params[i]);
			}
			rs = ps.executeQuery();
			String names[] = getColumnNames(rs);
			while(rs.next()){
				SParamMap map = new SParamMap();
				list.add(map);
				for (String name : names) {
					map.put(name, rs.getObject(name));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			SBaseUtils.close(ps);
			SBaseUtils.close(rs);
		}
		return list;
	}
	public static int update(String sql,Connection conn,Object...params){
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			if(params!=null)
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i+1, params[i]);
			}
			return ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("err-sql->"+sql);
		}finally{
			SBaseUtils.close(ps);
		}
		return 0;
	}
//	public static void main(String[] args) throws Exception {
//		System.out.println(getConnection("com.mysql.jdbc.Driver", "jdbc:mysql://localhost:3306/test", "root", "123456"));
//		Properties p = new Properties();
//        p.setProperty("driverClassName", "com.mysql.jdbc.Driver");
//        p.setProperty("url", "jdbc:mysql://localhost:3306/test");
//        p.setProperty("username", "root");
//        p.setProperty("password", "123456");
//        p.setProperty("maxActive", "30");
//        p.setProperty("maxIdle", "10");
//        p.setProperty("maxWait", "1000");
//        p.setProperty("removeAbandoned", "false");
//        p.setProperty("removeAbandonedTimeout", "120");
//        p.setProperty("testOnBorrow", "true");
//        p.setProperty("logAbandoned", "true");
//        BasicDataSource dataSource = (BasicDataSource) BasicDataSourceFactory.createDataSource(p);
//        Connection conn = dataSource.getConnection();
//        System.out.println(dataSource.getNumActive());
//        conn.close();
//        System.out.println(dataSource.getNumActive());
//	}
	public static String getDBType(Connection conn){
		try {
			return conn.getMetaData().getDatabaseProductName();
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}
}
